package com.hup.utils.commons;


import com.hup.utils.commons.exception.AppCommonException;

import java.text.NumberFormat;

public class NumberUtil {

    /**
     * 不用科学计数法打印double的格式
     */
    private static final NumberFormat NF_NORMAL = NumberFormat.getInstance();
    static {
        NF_NORMAL.setGroupingUsed(false);
    }

    public static Double getDouble(String str, String desc) {
        if (TextUtil.isBlank(str)) {
            return null;
        } else {
            try {
                return Double.parseDouble(str);
            } catch (NumberFormatException e) {
                throw new AppCommonException(desc + "输入错误:" + str);
            }
        }
    }

    /**
     * @return isSafe
     */
    public static boolean checkInt(String text, int st, int ed) {
        try {
            int i = Integer.parseInt(text);
            return i >= st && i <= ed;
        } catch(NumberFormatException e) {
            return false;
        }
    }

    public static int getInt(String str, String errMsg) {
        try {
            return Integer.parseInt(str);
        } catch(NumberFormatException e) {
            throw new RuntimeException(errMsg);
        }
    }

    /**
     * @return 全部都不等->false
     */
    public static boolean equalOr(int target, int... values) {
        for(int v : values) {
            if(target == v) {
                return true;
            }
        }
        return false;
    }

//    /**
//     * 四舍五入,采用BigDecimal(不行!,要用原生的)
//     *
//     * @param d
//     * @param digit
//     * @return null if null
//     */
//    public static Double round(Double d, int digit) {
//        //https://www.cnblogs.com/huangwenjie/p/6596833.html#autoid-h3-0-0-0
//        if(d == null) return null;
//        return new BigDecimal(d).setScale(digit, BigDecimal.ROUND_HALF_UP).doubleValue();
//    }

//	 /**
//     * 使用数学计算方法 实现四舍五入
//     * @param digit 保留n位小数
//     * @return nullable
//     */
//    public static Double mathRound(Number num, int digit) {
//        if(num == null) return null;
////        double pow = Math.pow(10, digit);
////        //+0.00000001 是为了处理0.4999999999, 如果是1.000000001+0.00000001则不会有差别
////        double round = Math.round(((num).doubleValue()+0.00000001)*pow)/pow;
////        return round;
//        return mathRoundNotNull(num, digit);
//    }
    
    public static double round(Number num, int digit) {
        //new DecimalFormat("#.00").format(444.215);是错的
        //new BigDecimal(444.215)也是错误的, 444.214999999999974988895701
        //BigDecimal bigDecimal = new BigDecimal(num.doubleValue());//错的
        //return bigDecimal.setScale(digit, RoundingMode.HALF_UP).doubleValue();
        double pow = Math.pow(10, digit);
        if(num.doubleValue() >= 0) {
            // +0.00000001 是为了处理0.4999999999, 如果是1.000000001+0.00000001则不会有差别
            return Math.round((num.doubleValue() + 0.00000001) * pow) / pow;
        } else {
            //在数学中，负数的四舍五入和正数的四舍五入计算方法一样。不考虑符号，只考虑有效小数的位数和数值
            return -Math.round((-num.doubleValue() + 0.00000001) * pow) / pow;
        }
    }


    public static Double roundNull(Number num, int digit) {
        if(num == null) return null;
        return round(num, digit);
    }

    public static String printDouble(double d) {
        return NF_NORMAL.format(d);
    }

    public static boolean isAEeqB(Double a, double b) {
        return a != null && a >= b;
    }

    /**
     * 获取int的数字位数个数
     */
    public static int getDigitCount(int v) {
        int count = 0;
        while (v > 0) {
            v = v / 10;
            count++;
        }
        return count;
    }

    /**
     * 均值计算辅助类:遇到null时,不累加不累除
     */
    public static class AvgCounter {

        private double sum = 0;
        private long count = 0;

        public void count(Double d) {
            if (d == null) return;
            sum += d;
            count++;
        }

        /**
         * 计算: '一堆均值的均值'(d带'步长')的情况:
         * 即: avg = (d1*5+d2*6+...)/(5+6+...)
         */
        public void count(double d, long count) {
            sum += (d * count);
            this.count += count;
        }

        /**
         * @return null-没有数量时
         */
        public Double avg(int digit) {
            return count == 0 ? null : NumberUtil.round(sum / count, digit);
        }

        public Double sum(int digit) {
            return count == 0 ? null : NumberUtil.round(sum, digit);
        }

        public long getCount() {
            return count;
        }
    }

    public static class IntCounter {
        private int count = 0;

        public void count(int i) {
            count += i;
        }

        public synchronized int syncCount(Integer i) {
            if (i != null) {
                count += i;
            }
            return count;
        }

        public int total() {
            return count;
        }
    }

}
